.
Conversion Rate Optimization For E-COMMERCE
Introducción
Impulsar el crecimieno en ventas del E-Commerce por medio de:
Analizar situación actual en base a tres áreas de enfoque: Ventas, Clientes y Productos.(Establecer el baseline).
Determinar las mejores estrategias de CRO (Conversion Rate Optimization) adecuadas en base a los datos obtenidos.
Herramientas:
El proyecto se aborda implementando Python por medio de Jupyter notebook, con los siguientes paquetes: Pandas, Numpy, Matplotlib, Scipy, Plotly, Seaborn y SqlAlchemy.
Data Set:
La empresa cuenta con una base de datos SQL Server desde donde administra toda su información transaccional.
# Se importan los pquetes requeridos
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import sqlalchemy as sa
#Automcompletar rápido
%config IPCompleter.greedy=True
#Formato de display
pd.options.display.float_format = '{:15.2f}'.format
#Estilo de sns
sns.set_theme(style="whitegrid")
# Conexión a la base de datos y carga de los datos iniciales.
con = sa.create_engine('sqlite:///../Datos/ecommerce.db')
# Inspeccion de tablas existentes.
from sqlalchemy import inspect
insp = inspect(con)
tablas = insp.get_table_names()
tablas
['2019-Dec', '2019-Nov', '2019-Oct', '2020-Feb', '2020-Jan']
# Creando df a partir de las tablas.
oct = pd.read_sql('2019-Oct', con)
nov = pd.read_sql('2019-Nov', con)
dic = pd.read_sql('2019-Dec', con)
ene = pd.read_sql('2020-Jan', con)
feb = pd.read_sql('2020-Feb', con)
# integración de tablas y datos en un único DataFrame
df = pd.concat([oct,nov,dic,ene,feb], axis = 0)
df
index | event_time | event_type | product_id | category_id | category_code | brand | price | user_id | user_session | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 68 | 2019-10-01 00:01:46 UTC | view | 5843665 | 1487580005092295511 | None | f.o.x | 9.44 | 462033176 | a18e0999-61a1-4218-8f8f-61ec1d375361 |
1 | 72 | 2019-10-01 00:01:55 UTC | cart | 5868461 | 1487580013069861041 | None | italwax | 3.57 | 514753614 | e2fecb2d-22d0-df2c-c661-15da44b3ccf1 |
2 | 95 | 2019-10-01 00:02:50 UTC | view | 5877456 | 1487580006300255120 | None | jessnail | 122.22 | 527418424 | 86e77869-afbc-4dff-9aa2-6b7dd8c90770 |
3 | 122 | 2019-10-01 00:03:41 UTC | view | 5649270 | 1487580013749338323 | None | concept | 6.19 | 555448072 | b5f72ceb-0730-44de-a932-d16db62390df |
4 | 124 | 2019-10-01 00:03:44 UTC | view | 18082 | 1487580005411062629 | None | cnd | 16.03 | 552006247 | 2d8f304b-de45-4e59-8f40-50c603843fe5 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
429785 | 4156660 | 2020-02-29 23:58:49 UTC | cart | 5815662 | 1487580006317032337 | None | None | 0.92 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429786 | 4156663 | 2020-02-29 23:58:57 UTC | view | 5815665 | 1487580006317032337 | None | None | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429787 | 4156668 | 2020-02-29 23:59:05 UTC | cart | 5815665 | 1487580006317032337 | None | None | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429788 | 4156675 | 2020-02-29 23:59:28 UTC | view | 5817692 | 1487580010872045658 | None | None | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d |
429789 | 4156680 | 2020-02-29 23:59:54 UTC | view | 5716351 | 1487580010872045658 | None | irisk | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d |
2095076 rows × 10 columns
# Tipos de Variables
df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 2095076 entries, 0 to 429789 Data columns (total 10 columns): # Column Dtype --- ------ ----- 0 index int64 1 event_time object 2 event_type object 3 product_id int64 4 category_id int64 5 category_code object 6 brand object 7 price float64 8 user_id int64 9 user_session object dtypes: float64(1), int64(4), object(5) memory usage: 175.8+ MB
# Eliminar la columna Index
df.drop(columns = 'index', inplace = True)
# Corregir tipo de datos. pasar event_time a datetime
def datetime_rapido(dt,formato):
def divide_fecha(fecha):
division = fecha.split()
date = division[0]
time = division[1]
cadena = date + ' ' + time
return cadena
resultado = pd.to_datetime(dt.apply(lambda x: divide_fecha(x)), format = formato)
return resultado
# llamando a la función y mostando cambios
formato = '%Y-%m-%d %H:%M:%S'
df.event_time = datetime_rapido(df.event_time,formato)
df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 2095076 entries, 0 to 429789 Data columns (total 9 columns): # Column Dtype --- ------ ----- 0 event_time datetime64[ns] 1 event_type object 2 product_id int64 3 category_id int64 4 category_code object 5 brand object 6 price float64 7 user_id int64 8 user_session object dtypes: datetime64[ns](1), float64(1), int64(3), object(4) memory usage: 159.8+ MB
# Renombramos las variables a español
df.columns = ['fecha',
'evento',
'producto',
'categoria',
'categoria_cod',
'marca',
'precio',
'usuario',
'sesion']
# Análisis de nulos
df.isna().sum().sort_values(ascending = False)
categoria_cod 2060411 marca 891646 sesion 506 fecha 0 evento 0 producto 0 categoria 0 precio 0 usuario 0 dtype: int64
Summary:
Acciones:
df = df.drop(columns = ['categoria_cod','marca']).dropna()
# Seleccion de variables con precio positivo
df = df[df.precio > 0]
df
fecha | evento | producto | categoria | precio | usuario | sesion | |
---|---|---|---|---|---|---|---|
0 | 2019-10-01 00:01:46 | view | 5843665 | 1487580005092295511 | 9.44 | 462033176 | a18e0999-61a1-4218-8f8f-61ec1d375361 |
1 | 2019-10-01 00:01:55 | cart | 5868461 | 1487580013069861041 | 3.57 | 514753614 | e2fecb2d-22d0-df2c-c661-15da44b3ccf1 |
2 | 2019-10-01 00:02:50 | view | 5877456 | 1487580006300255120 | 122.22 | 527418424 | 86e77869-afbc-4dff-9aa2-6b7dd8c90770 |
3 | 2019-10-01 00:03:41 | view | 5649270 | 1487580013749338323 | 6.19 | 555448072 | b5f72ceb-0730-44de-a932-d16db62390df |
4 | 2019-10-01 00:03:44 | view | 18082 | 1487580005411062629 | 16.03 | 552006247 | 2d8f304b-de45-4e59-8f40-50c603843fe5 |
... | ... | ... | ... | ... | ... | ... | ... |
429785 | 2020-02-29 23:58:49 | cart | 5815662 | 1487580006317032337 | 0.92 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429786 | 2020-02-29 23:58:57 | view | 5815665 | 1487580006317032337 | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429787 | 2020-02-29 23:59:05 | cart | 5815665 | 1487580006317032337 | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 |
429788 | 2020-02-29 23:59:28 | view | 5817692 | 1487580010872045658 | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d |
429789 | 2020-02-29 23:59:54 | view | 5716351 | 1487580010872045658 | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d |
2074026 rows × 7 columns
# Cantidad de eventos
df.evento.nunique()
4
# Frcuencia de eventos
df.evento.value_counts()
view 961558 cart 574547 remove_from_cart 410357 purchase 127564 Name: evento, dtype: int64
# Cantidad de prodctos distintos.
df.producto.nunique()
45327
# Cantidad de categorias de producto.
df.categoria.nunique()
508
#Asignando la fecha como indice
df.set_index('fecha', inplace = True)
# Funcion para segmentar dateTime
def componentes_fecha(dataframe):
date = dataframe.index.date
año = dataframe.index.year
mes = dataframe.index.month
dia = dataframe.index.day
hora = dataframe.index.hour
minuto = dataframe.index.minute
segundo = dataframe.index.second
return(pd.DataFrame({'date':date, 'año':año,'mes':mes, 'dia':dia, 'hora':hora, 'minuto':minuto, 'segundo':segundo}))
# LLamando a la funcion y creando nuevo df
df = pd.concat([df.reset_index(),componentes_fecha(df)], axis = 1).set_index('fecha')
df
evento | producto | categoria | precio | usuario | sesion | date | año | mes | dia | hora | minuto | segundo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
fecha | |||||||||||||
2019-10-01 00:01:46 | view | 5843665 | 1487580005092295511 | 9.44 | 462033176 | a18e0999-61a1-4218-8f8f-61ec1d375361 | 2019-10-01 | 2019 | 10 | 1 | 0 | 1 | 46 |
2019-10-01 00:01:55 | cart | 5868461 | 1487580013069861041 | 3.57 | 514753614 | e2fecb2d-22d0-df2c-c661-15da44b3ccf1 | 2019-10-01 | 2019 | 10 | 1 | 0 | 1 | 55 |
2019-10-01 00:02:50 | view | 5877456 | 1487580006300255120 | 122.22 | 527418424 | 86e77869-afbc-4dff-9aa2-6b7dd8c90770 | 2019-10-01 | 2019 | 10 | 1 | 0 | 2 | 50 |
2019-10-01 00:03:41 | view | 5649270 | 1487580013749338323 | 6.19 | 555448072 | b5f72ceb-0730-44de-a932-d16db62390df | 2019-10-01 | 2019 | 10 | 1 | 0 | 3 | 41 |
2019-10-01 00:03:44 | view | 18082 | 1487580005411062629 | 16.03 | 552006247 | 2d8f304b-de45-4e59-8f40-50c603843fe5 | 2019-10-01 | 2019 | 10 | 1 | 0 | 3 | 44 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2020-02-29 23:58:49 | cart | 5815662 | 1487580006317032337 | 0.92 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 | 2020-02-29 | 2020 | 2 | 29 | 23 | 58 | 49 |
2020-02-29 23:58:57 | view | 5815665 | 1487580006317032337 | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 | 2020-02-29 | 2020 | 2 | 29 | 23 | 58 | 57 |
2020-02-29 23:59:05 | cart | 5815665 | 1487580006317032337 | 0.59 | 147995998 | 5ff96629-3627-493e-a25b-5a871ec78c90 | 2020-02-29 | 2020 | 2 | 29 | 23 | 59 | 5 |
2020-02-29 23:59:28 | view | 5817692 | 1487580010872045658 | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d | 2020-02-29 | 2020 | 2 | 29 | 23 | 59 | 28 |
2020-02-29 23:59:54 | view | 5716351 | 1487580010872045658 | 0.79 | 619841242 | 18af673b-7fb9-4202-a66d-5c855bc0fd2d | 2020-02-29 | 2020 | 2 | 29 | 23 | 59 | 54 |
2074026 rows × 13 columns
# Indicadores exógenos de feriados importantes.
df['black_friday'] = 0
df.loc['2019-11-29','black_friday'] = 1
df['san_valentin'] = 0
df.loc['2020-02-14','san_valentin'] = 1
# Tablón Analitico final
df.head()
evento | producto | categoria | precio | usuario | sesion | date | año | mes | dia | hora | minuto | segundo | black_friday | san_valentin | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
fecha | |||||||||||||||
2019-10-01 00:01:46 | view | 5843665 | 1487580005092295511 | 9.44 | 462033176 | a18e0999-61a1-4218-8f8f-61ec1d375361 | 2019-10-01 | 2019 | 10 | 1 | 0 | 1 | 46 | 0 | 0 |
2019-10-01 00:01:55 | cart | 5868461 | 1487580013069861041 | 3.57 | 514753614 | e2fecb2d-22d0-df2c-c661-15da44b3ccf1 | 2019-10-01 | 2019 | 10 | 1 | 0 | 1 | 55 | 0 | 0 |
2019-10-01 00:02:50 | view | 5877456 | 1487580006300255120 | 122.22 | 527418424 | 86e77869-afbc-4dff-9aa2-6b7dd8c90770 | 2019-10-01 | 2019 | 10 | 1 | 0 | 2 | 50 | 0 | 0 |
2019-10-01 00:03:41 | view | 5649270 | 1487580013749338323 | 6.19 | 555448072 | b5f72ceb-0730-44de-a932-d16db62390df | 2019-10-01 | 2019 | 10 | 1 | 0 | 3 | 41 | 0 | 0 |
2019-10-01 00:03:44 | view | 18082 | 1487580005411062629 | 16.03 | 552006247 | 2d8f304b-de45-4e59-8f40-50c603843fe5 | 2019-10-01 | 2019 | 10 | 1 | 0 | 3 | 44 | 0 | 0 |
# Frecuencia de eventos
eventos = df.evento.value_counts()
eventos
view 961558 cart 574547 remove_from_cart 410357 purchase 127564 Name: evento, dtype: int64
# Generación de kpi Customer Journey
kpi_visualizaciones_p = 100
kpi_carrito_p = eventos.loc['cart'] / eventos.loc['view'] * 100
kpi_abandono_p = eventos.loc['remove_from_cart'] / eventos.loc['cart'] * 100
kpi_compra_p = eventos.loc['purchase'] / eventos.loc['cart'] * 100
kpis = pd.DataFrame({'kpi':['visitas','carrito','compra'],
'valor':[kpi_visualizaciones_p,kpi_carrito_p,kpi_compra_p]})
kpis
kpi | valor | |
---|---|---|
0 | visitas | 100.00 |
1 | carrito | 59.75 |
2 | compra | 22.20 |
# Visualizando el embudo de Ventas
from plotly import graph_objects as go
fig = go.Figure(go.Funnel(
y = kpis.kpi,
x = kpis.valor.round(2),
marker = {'color': ['red','blue','green']},
opacity = 0.3
))
fig.update_layout(
title = 'Funnel Conversión Inicial')
fig.show()
Conclusiones:
# generando dataframe agregado para analizar sesiones.
sesion_prod = df.groupby(['sesion','evento']).producto.count()
sesion_prod = sesion_prod.unstack().fillna(0)
sesion_prod = sesion_prod[['view','cart','remove_from_cart','purchase']]
# media de cada evento por sesión
media_eventos_sesion = sesion_prod.mean()
media_eventos_sesion
evento view 2.16 cart 1.29 remove_from_cart 0.92 purchase 0.29 dtype: float64
Conclusión:
En cada sesión, de media:
Estos números representan el objetivo de las acciones de CRO para lograr los incrementos.
# generando dataframe agregado para analizar sesiones.
eventos_hora = df.groupby(['evento','hora']).producto.count()
eventos_hora = eventos_hora.unstack(level = 0)
# crear una nueva variable que sea el ratio de compras por visita en cada hora.
eventos_hora['compras_visitas'] = eventos_hora.purchase / eventos_hora.view * 100
eventos_hora = eventos_hora[['view','cart','remove_from_cart','purchase','compras_visitas']]
# Analizamos los horarios de compra.
plt.figure(figsize = (10,4))
sns.lineplot(data = eventos_hora, x = eventos_hora.index, y = 'compras_visitas')
plt.xticks(eventos_hora.index);
# titpificar variables para unificar escalas y generar mapa de calor por hora
def tipificar(variable):
media = variable.mean()
dt = variable.std()
return(variable.apply(lambda x: (x - media) / dt))
# llamando a la función
eventos_hora_tip = eventos_hora.apply(tipificar)
# Mapa de calor agregado por eventos en cada horario
plt.figure(figsize = (12,12))
sns.heatmap(data = eventos_hora_tip);
INSIGHT #1: Todas las métricas se maximizan en las franjas entre las 9:00 y las 13:00 y entre las 18:00 y las 20:00
# Media de facturacion mensual
df.loc[df.evento == 'purchase'].groupby('mes').precio.sum().mean()
124309.92
Esta variable es importante porque representa el ticket medio por mes (125000 $), el cual será nuestro barómetro de crecimiento.
# Analizando la tendencia de facturacion mensual
tendencia = df.groupby('evento').resample('W').evento.count().unstack(level = 0)
tendencia = tendencia[['view','cart','remove_from_cart','purchase']]
tendencia.plot(subplots = True, figsize = (12,6), sharex = True, xticks = tendencia.index, x_compat=True, rot = 90);
INSIGHT #2: La gran conclusión es que todo el pastel de las compras navideñas se reparte en la semana del black friday
# Creando un df agregado por clientes y 3 variables importantes.
clientes = df.loc[df.evento == 'purchase'].groupby(['usuario']).agg({'producto':'count',
'sesion':'nunique',
'precio': 'mean',
'date': 'max'})
clientes.columns = ['productos_tot_num','compras_tot_num','precio_medio_prod','ult_compra']
# Generando 2 nuevas variables
clientes['gasto_tot'] = clientes.productos_tot_num * clientes.precio_medio_prod
clientes['productos_por_compra'] = clientes.productos_tot_num / clientes.compras_tot_num
clientes
productos_tot_num | compras_tot_num | precio_medio_prod | ult_compra | gasto_tot | productos_por_compra | |
---|---|---|---|---|---|---|
usuario | ||||||
25392526 | 3 | 1 | 7.38 | 2019-12-18 | 22.14 | 3.00 |
27756757 | 1 | 1 | 20.63 | 2020-01-27 | 20.63 | 1.00 |
50748978 | 9 | 1 | 1.11 | 2019-12-14 | 10.01 | 9.00 |
52747911 | 3 | 1 | 7.67 | 2019-10-10 | 23.02 | 3.00 |
65241811 | 5 | 1 | 8.36 | 2019-11-11 | 41.79 | 5.00 |
... | ... | ... | ... | ... | ... | ... |
621995551 | 5 | 1 | 2.09 | 2020-02-29 | 10.46 | 5.00 |
622021687 | 1 | 1 | 13.33 | 2020-02-29 | 13.33 | 1.00 |
622041514 | 3 | 1 | 0.63 | 2020-02-29 | 1.90 | 3.00 |
622042698 | 3 | 1 | 28.04 | 2020-02-29 | 84.13 | 3.00 |
622065819 | 4 | 1 | 5.12 | 2020-02-29 | 20.48 | 4.00 |
11040 rows × 6 columns
# analizando la distribucion de clientes en cuanto a gasto
sns.histplot(data = clientes, x = 'gasto_tot', bins = 50)
plt.xlim([0,300]);
La gran mayoría de los clientes han gastado menos de 50€ en el período.
# Analizando clientes por su frecuencia de compra.
sns.countplot(data = clientes, x = 'compras_tot_num');
INSIGHT #3: La gran mayoría de los clientes sólo hace una compra.
Existe gran recorrido para mejorar este ratio mediante:
# Analizando clientes por cantidad de productos en cada compra.
clientes.productos_por_compra.describe()
count 11040.00 mean 7.79 std 9.49 min 1.00 25% 3.00 50% 5.00 75% 10.00 max 219.00 Name: productos_por_compra, dtype: float64
INSIGHT #4: La compra mediana incluye 5 productos.
Pero un 25% de los clientes compran más de 10 productos en la misma compra.
Existe gran recorrido para mejorar este ratio mediante:
# Analizando clientes por gasto total medio
clientes.gasto_tot.describe()
count 11040.00 mean 56.30 std 81.73 min 0.13 25% 16.22 50% 32.74 75% 60.30 max 1559.21 Name: gasto_tot, dtype: float64
INSIGHT #5: Existen clientes con gasto medio bastante alto, hasta decenas de veces superior a la media. Representan al segmento de alta facturación.
Se sugiere atraer a estos clientes mediante programas de fidelización.
# Creando un df agregado a nivel de productos
prod = df.groupby(['producto','evento']).size()
prod = prod.unstack(level = 1).fillna(0)
# Se crea una matriz de precios para hacer join con el df, y se reordena.
maestro_precios = df.groupby('producto', as_index = False).precio.mean()
prod = pd.merge(left = prod, right = maestro_precios, how = 'left', on = 'producto')
prod = prod[['producto','view','cart','remove_from_cart','purchase','precio']]
prod
producto | view | cart | remove_from_cart | purchase | precio | |
---|---|---|---|---|---|---|
0 | 3752 | 10.00 | 0.00 | 0.00 | 0.00 | 15.71 |
1 | 3762 | 258.00 | 127.00 | 59.00 | 28.00 | 19.29 |
2 | 3763 | 51.00 | 10.00 | 2.00 | 2.00 | 16.00 |
3 | 3771 | 9.00 | 0.00 | 0.00 | 0.00 | 15.08 |
4 | 3774 | 76.00 | 26.00 | 13.00 | 7.00 | 15.92 |
... | ... | ... | ... | ... | ... | ... |
45322 | 5932537 | 1.00 | 1.00 | 0.00 | 0.00 | 1.43 |
45323 | 5932538 | 1.00 | 0.00 | 0.00 | 0.00 | 1.43 |
45324 | 5932540 | 2.00 | 1.00 | 0.00 | 0.00 | 1.43 |
45325 | 5932578 | 1.00 | 0.00 | 0.00 | 0.00 | 6.02 |
45326 | 5932585 | 2.00 | 0.00 | 0.00 | 0.00 | 6.33 |
45327 rows × 6 columns
# produtos que no se venden
prod[prod.purchase == 0]
producto | view | cart | remove_from_cart | purchase | precio | |
---|---|---|---|---|---|---|
0 | 3752 | 10.00 | 0.00 | 0.00 | 0.00 | 15.71 |
3 | 3771 | 9.00 | 0.00 | 0.00 | 0.00 | 15.08 |
6 | 3790 | 10.00 | 0.00 | 0.00 | 0.00 | 7.92 |
8 | 3809 | 2.00 | 0.00 | 0.00 | 0.00 | 12.54 |
9 | 3812 | 1.00 | 0.00 | 0.00 | 0.00 | 12.54 |
... | ... | ... | ... | ... | ... | ... |
45322 | 5932537 | 1.00 | 1.00 | 0.00 | 0.00 | 1.43 |
45323 | 5932538 | 1.00 | 0.00 | 0.00 | 0.00 | 1.43 |
45324 | 5932540 | 2.00 | 1.00 | 0.00 | 0.00 | 1.43 |
45325 | 5932578 | 1.00 | 0.00 | 0.00 | 0.00 | 6.02 |
45326 | 5932585 | 2.00 | 0.00 | 0.00 | 0.00 | 6.33 |
21850 rows × 6 columns
INSIGHT #6: Casi la mitad de los productos no han tenido ninguna venta en los 5 meses del histórico.
Se podrían eliminar del catálogo, o como mínimo de la tienda, newsletter, etc, para que no ocupen espacio de los productos que sí se venden.
# Analizando la relación entre precio y volumen de ventas de los productos.
# Ya que este análisis incluye las ventas vamos a eliminar los productos que no han tenido ninguna.
sns.scatterplot(data = prod[prod.purchase > 0], x = 'precio', y = 'purchase', hue = 'precio');
Sí que existe una clara relación decreciente.
# analizando 20 de los productos mas vistos
prod.view.sort_values(ascending = False)[0:20].plot.bar();
Es posible incrementar las ventas y el ticket medio destacando estos productos en la tienda Siempre que además de ser vistos también se vendan.
# Analizando productos muy vistos y poco comprados
# Por ejemplo productos que miran muchos clientes pero que luego no los compran.
sns.scatterplot(data = prod, x = 'view', y = 'purchase');
# quitando el atípico y haciendo zoom en la ventana de muchas vistas pocas compras.
sns.scatterplot(data = prod.loc[prod.view < 4000], x = 'view', y = 'purchase', hue = 'precio')
plt.xlim(1000,3000)
plt.ylim(0,150);
Hay una oportunidad con estos productos, porque por algún motivo generan el interés de los clientes, pero finalmente no los compran.
La tendencia actual es plana en todas las métricas, lo que confirma la necesidad de las acciones de CRO (Conversion Rate Optimization).
Tras el análisis realizado sobre los datos transaccionales, se ha desarrollado un plan CRO de 8 iniciativas concretas, organizadas en 5 grandes palancas o áreas de negocio que, con alta probabilidad y de acuerdo a los datos ahora conocidos, van a impulsar los baselines, consiguiendo un incremento global de los ingresos del ecommerce. Los datos trazan el camino mas eficiente para obtener resultados ganadores.
Los resultados analiticos indican que el Ecommerce presenta los siguientes valores promedio por cada sesión:
KPIs por sesión: Se ven 2.2 productos
KPIs por sesión: Se añaden 1.3 productos al carrito
KPIs por sesión: Se eliminan 0.9 productos del carrito
KPIs por sesión: Se compran 0.3 productos
Venta cruzada: mediana de 5 productos por compra
Recurrencia: el 10% de los clientes vuelve a comprar tras el primer mes
Conversión: 60% de añadir al carrito sobre visualizaciones
Conversión: 22% de compra sobre añadidos a carrito
Conversión: 13% de compra sobre visualizaciones
Facturación media mensual: 125.000€
El 90% de los clientes sólo hace una compra.
Es recomendable en este caso, generar un BUSINESS CASE para observar:
1. las 8 acciones de CRO recomendadas dentro de un plan.
2. Los Presupuestos, proyecciones y escenarios de rentabilidad.
.
.